package cn.agiledata.bank.common.dao;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.common.util.PageBean;
import cn.agiledata.bank.common.util.StringUtil;
import com.vnv.infrastructure.logic.IPBAppFactory;

public abstract class SqlPageListTemplate extends HibernateDaoSupport implements
		PageList {
	public abstract Object getEntityObject();

	public abstract String getSQLName();

	public abstract String getPageRecord();

	public abstract Map getParams() ;

	public abstract String getStartPage();
	

	public PageBean getAccountListPageBean() {
		// TODO Auto-generated method stub
		this.setSessionFactory(
				(SessionFactory)IPBAppFactory.getObj("sessionFactory"));
		PageBean pb = 
			new PageBean(getPageCount(),getFirst(),Integer.parseInt(StringUtil.isStrEmpty(getPageRecord())?Constant.PAGESIZE.toString():getPageRecord() ));
		pb.setData(getPageList());
		return pb;
	}
	private List getPageList() {
		Query query = this.getNamedQuery();
		return getList(parsePaging(parseParams(query)));
	}
	private Query parsePaging(Query query) {
		int startPage = Integer.parseInt(getStartPage());
		int pageRecord = Integer.parseInt(getPageRecord());
		query.setFirstResult((startPage-1) * pageRecord);
		query.setMaxResults(pageRecord);	
		return query;
	}
	private List getList(Query query) {
		return query.list();
	}
	/**
	 * 得到起始页
	 * @return
	 */
	public int getFirst() {
		String startPage = getStartPage();
		int startPageNo = 1;
		if (startPage!=null && !startPage.equals("")){
			startPageNo = Integer.parseInt(startPage);
		}	
		return startPageNo;
	}
	private int getPageCount() {
		Query q = getHibernateTemplate().getSessionFactory()
		.getCurrentSession().createSQLQuery(parseCountHql()).
		addScalar("count", Hibernate.LONG);
		
		return getCount(parseParams(q));
	}
	private String parseCountHql() {
		String countHqlPrefix =
			"select count(*) as count ";
		return countHqlPrefix + filterHql();
	}
	private String filterHql() {
		String string = getNamedQuery().getQueryString();
		int start = string.indexOf("from");
		string = string.substring(start);
		return string;
	}
	private Query getNamedQuery() {
		Query q = getHibernateTemplate().getSessionFactory()
		.getCurrentSession().getNamedQuery(getSQLName());
		return q;
	}
	private Query parseParams(Query query) {
		Map map = getParams();
		if(map != null) {
			Set set = map.keySet();
			if(set != null) {
				Iterator iterator = set.iterator();
				while(iterator.hasNext()) {
					String key = (String)iterator.next();
					Object value = (Object)map.get(key);
					if (value instanceof List) {
						query.setParameterList(key, (Collection) value);
					} else {
						query.setParameter(key,value);
					}
				}
			}
		}
		return query;
	}
	private int getCount(Query query) {
		return ((Long)query.uniqueResult()).intValue();
	}
}
